Index


RISC World

Easy C++ Manual

Copyright © ProAction and APDL, 2001

String handling <string.h>

The header <string.h> declares one type and several functions, and defines one macro useful for manipulating arrays of character type and other objects treated as arrays of character type. Various methods are used for determining the lengths of the arrays, but in all cases a char * or void * argument points to the initial (lowest addressed) character of the array. If the array is accessed beyond the end of an object, the behaviour is undefined.

The type size_t is the unsigned integral type of the result of the sizeof operator.

The macro NULL expands to an implementation-defined null pointer constant.

Copying functions

   Name    memcpy

   Syntax    void *memcpy(void *s1, const void *s2, size_t n);

   Description    Copy n characters from the object pointed to by s2 into the object pointed to by s1 . If copying takes place between objects that overlap, the behaviour is undefined.

   Returns    The value of s1 .

   Name    memmove

   Syntax    void *memmove(void *s1, const void *s2, size_t n);

   Description    Copy n characters from the object pointed to by s2 into the object pointed to by s1 . Copying takes place as if n characters from the object pointed to by s2 are first copied into a temporary array of n characters that does not overlap the objects pointed to by s1 and s2 , and then the n characters from the temporary array are copied into the object pointed to by s1 .

   Returns    The value of s1 .

   Name    strcpy

   Syntax    char *strcpy(char *s1, const char *s2);

   Description    strcpy copies the string pointed to by s2 (including the terminating null character) into the array pointed to by s1 .

   Returns    the value of s1 .

   Name    strncpy

   Syntax    char *strncpy(char *s1, const char *s2, size_t n);

   Description    Copy not more than n characters (characters that follow a null character are not copied) from the array pointed to by s2 to the array pointed to by s1 . If copying takes place between objects that overlap, the behaviour is undefined.

If the array pointed to by s2 is a string that is shorter than n characters, null characters are appended to the copy in the array pointed to by s1 , until n characters in all have been written.

   Returns    The value of s1 .

Concatenation functions

   Name    strcat

   Syntax    char *strcat(char *s1, const char *s2);

   Description    Appends a copy of the string pointed to by s2 (including the terminating null character) to the end of the string pointed to by s1 . The initial character of s2 overwrites the null character at the end of s1 . If copying takes place between objects that overlap, the behaviour is undefined.

   Returns    The value of s1 .

   Name    strncat

   Syntax    char *strncat(char *s1, const char *s2, size_t n);

   Description    Append not more than n characters (a null character and characters that follow it are mot appended) of the array pointed to by s2 to the end of the string pointed to by s1 . The initial character of s2 overwrites the null character at the end of s1 . A terminating null character is always appended to the result. If copying takes place between objects that overlap, the behaviour is undefined.

   Returns    The value of s1 .

Comparison functions

The sign of a nonzero value returned by the comparison functions memcmp , strcmp , and strncmp is determined by the sign of the difference between the values of the first pair of characters (both interpreted as unsigned char ) that differ in the objects being compared.

   Name    memcmp

   Syntax    int memcmp(const void *s1, const void *s2, size_t n);

   Description    Compare the first n characters of the object pointed to by s1 to the first n characters of the object pointed to by s2 .

   Returns    An integer greater than, equal to, or less than zero, accordingly as the object pointed to by s1 is greater than, equal to, or less than the object pointed to by s2 .

   Name    strcmp

   Syntax    int strcmp(const char *s1, const char *s2);

   Description    Compare the string pointed to by s1 to the string pointed to by s2 .

   Returns    An integer greater than, equal to, or less than zero, depending accordingly as the string pointed to by s1 is greater than, equal to, or less than the string pointed to by s2 .

   Name    strcoll

   Syntax    int strcoll (const char *s1, const char *s2);

   Description    Compare the string pointed to by s1 to the string pointed to by s2 , both interpreted as appropriate to the LC_COLLATE category of the current locale.

   Returns    An integer greater than, equal to, or less than zero accordingly as the string pointed to by s1 is greater than, equal to, or less than the string pointed to by s2 when both are interpreted as appropriate to the current locale.

   Name    strncmp

   Syntax    int strncmp(const char *s1, const char *s2, size_t n);

   Description    Compare not more than n characters (characters that follow a null character are not compared) from the array pointed to by s1 to the array pointed to by s2 .

   Returns    An integer greater than, equal to, or less than zero accordingly as the string pointed to by s1 is greater than, equal to, or less than the possibly null-terminated array pointed to by s2 .

   Name    strxfrm

   Syntax    size_t strxfrm (char *s1, const char *s2, size_t n);

   Description    Transform the string pointed to by s2 and places the resulting string into the array pointed to by s1 . The transformation is such that if the strcmp function is applied to two transformed strings, it returns a value greater than, equal to, or less than zero, corresponding to the result of the strcoll function applied to the same two original strings. No more than n characters are placed into the resulting array pointed to by s1 , including the terminating character. If n is zero, s1 is permitted to be a null pointer. If copying takes place between objects that overlap, the behaviour is undefined

   Returns    The length of the transformed string (not including the terminating null character). If the value returned is n or more, the contents of the array pointed to by s1 are indeterminate.

Search functions

   Name    memchr

   Syntax    void *memchr(const void *s, int c, size_t n);

   Description    Locate the first occurrence of c (converted to an unsigned char ) in the initial n characters (each interpreted as unsigned char ) of the object pointed to by s .

   Returns    A pointer to the located character, or a null pointer if the character does not occur in the object.

   Name    strchr

   Syntax    char *strchr(const char *s, int c);

   Description    Locate the first occurrence of c (converted to a char ) in the string pointed to by s . The terminating null character is considered to be part of the string.

   Returns    A pointer to the located character, or a null pointer if the character does not occur in the string.

   Name    strcspn

   Syntax    size_t strcspn(const char *s1, const char *s2);

   Description    Compute the length of the maximum initial segment of the string pointed to by s1 which consists entirely of characters not from the string pointed to by s2 .

   Returns    The length of the segment.

   Name    strpbrk

   Syntax    char *strpbrk(const char *s1, const char *s2);

   Description    Locate the first occurrence in the string pointed to by s1 of any character from the string pointed to by s2 .

   Returns    A pointer to the located character, or a null pointer if no character from s2 occurs in s1 .

   Name    strrchr

   Syntax    char *strrchr(const char *s, int c);

   Description    Locate the last occurrence of c (converted to char ) in the string pointed to by s . The terminating null character is considered to be part of the string.

   Returns    A pointer to the character, or a null pointer if c does not occur in the string.

   Name    strspn

   Syntax    size_t strspn(const char *s1, const char *s2);

   Description    Compute the length of the maximum initial segment of the string pointed to by s1 which consists entirely of characters from the string pointed to by s2 .

   Returns    The length of the segment.

   Name    strstr

   Syntax    char *strstr(const char *s1, const char *s2);

   Description    Locate the first occurrence in the string pointed to by s1 of the sequence of characters (excluding the terminating null character) in the string pointed to by s2 .

   Returns    A pointer to the located string, or a null pointer if the string is not found. If s2 points to a string with zero length, the function returns s1 .

   Name    strtok

   Syntax    char *strtok(char *s1, const char *s2);

   Description    A sequence of calls to the strtok function breaks the string pointed to by s1 into a sequence of tokens, each of which is delimited by a character from the string pointed to by s2 . The first call in the sequence has s1 as its first argument, and is followed by calls with a null pointer as their first argument. The separator string pointed to by s2 may be different from call to call.

The first call in the sequence searches the string pointed to by s1 for the first character that is not contained in the current separator string pointed to by s2 . If no such character is found, then there are no tokens in the string pointed to by s1 and the strtok function returns a null pointer. If such a character is found, it is the start of the first token.

The strtok function then searches from there for a character that is contained in the current separator string. If no such character is found, the current token extends to the end of the string pointed to by s1 , and subsequent searches for a token will return a null pointer. If such a character is found, it is overwritten by a null character, which terminates the current token. The strtok function saves a pointer to the following character, from which the next search for a token will start.

Each subsequent call, with a null pointer as the value of the first argument, starts searching from the saved pointer and behaves as described above.

   Returns    A pointer to the first character of a token, or a null pointer if there is no token.

Miscellaneous string functions

   Name    memset

   Syntax    void *memset(void *s, int c, size_t n);

   Description    Copy the value of c (converted to an unsigned char ) into each of the first n characters of the object pointed to by s .

   Returns    The value of s .

   Name    strerror

   Syntax    char *strerror(int errnum);

   Description    Map the error number in errnum to an error message string.

   Returns    A pointer to the string. The array pointed to shall not be modified by the program, but may be overwritten by a subsequent call to the strerror function.

   Name    strlen

   Syntax    size_t strlen(const char *s);

   Description    Compute the length of the string pointed to by s .

   Returns    The number of characters that precede the terminating null character.

This chapter lists in alphabetical order all the machine-specific functions supplied with Easy C. The syntax of each function is given with a brief description of what it does and what it returns. In addition, there is a self-contained example program for each function which demonstrates how it is used. For your convenience all the examples are supplied with EasyC disc in the directory Programs.OSExamples .

RISC OS functions are contained in the library ROSLib , and you should #include the header file roslib.h in any program that uses them. For further information about the operating system calls made by these functions, please refer to the Acorn Programmers Reference Manual for your computer system.

Many of the functions described in this chapter are of type os_error ; they return a pointer to an error if one has occurred, otherwise zero if the operation was successful. The example program below shows how to trap the error, and display the error number and error message.

/* Example of trapping an error */

/* Execute an illegal command to generate

   an error. */

#include <stdio.h>

#include "roslib.h"

void main(void)



  char s[] = "rubbish";

  e = os_cli(s);

  if (e)

  

    printf("Err msg : %s\n", e->errmess);

  }

  else

    printf("No error\n");

}

   Name    os_adval

   Syntax    int os_adval(int a);

   Description    Return the current x or y position of the mouse, or the number of bytes in a particular input buffer, or the number of bytes free in a particular output buffer.

   Returns    The integer returned depends on the value of the parameter a , as follows:

a    action 7    x coordinate of mouse 8    y coordinate of mouse 246    bytes in mouse buffer 252    bytes free in printer buffer 253    bytes free in RS423 output buffer 254    bytes in RS423 input buffer 255    bytes in keyboard buffer

   Example    /* Example of os_adval() */ /* Use os_adval() to print x and y coordinates of the mouse pointer. Press Esc to quit program. */ #include <stdio.h> #include "roslib.h" void main(void) while(1) y = os_adval(8); printf("x=%d y=%d\n", x, y); } }

   Name    os_args

   Syntax    os_error *os_args(regset *r);

   Description    Perform an OS_Args SWI call to read or write an open file's arguments, or to return the filing system type. The parameter r points to a structure of type regset , which contains an array of integers used to pass registers to OS_Args.

typedef struct



} regset;

   Returns    A pointer to an error if one has occurred, or zero if the operation was successful. See page 124 for further details.

   Example    /* Example of os_args() */ /* Create file "temp" in current directory, set it's extent to 64, and finally close file. */ #include "roslib.h" void main(void) int h; r.r[0] = 0x83; r.r[1] = "temp"; os_find(&r); h = r.r[0]; r.r[0] = 3; r.r[1] = h; r.r[2] = 64; os_args(&r); r.r[0] = 0; r.r[1] = h; os_find(&r); }

   Name    os_byte

   Syntax    os_error *os_byte(int a, int *x, int *y);

   Description    Perform an OS_Byte SWI call. Parameter a is the reason code which determines the action of the call. Parameters x and y are passed to registers R0 and R1. Please refer to your computer user guides for a list OS_Byte reason codes and parameters.

   Returns    A pointer to an error if one has occurred, or zero if the operation was successful. See page 124 for further details.

   Example    /* Example of os_byte() */ /* Read character at text cursor position, and current screen mode using OS_Byte 135. [stores it internally] */ #include <stdio.h> #include "roslib.h" void main(void) os_byte(135, &x, &y); printf("Character = %d\n", x); printf("Screen mode = %d\n", y); }

   Name    os_circle

   Syntax    os_error *os_circle(int x, int y, int r);

   Description    Draw a circle whose centre is at the coordinates specified by x and y , with a radius specified by r .

   Returns    A pointer to an error if one has occurred, or zero if the operation was successful. See page 124 for further details.

   Example    /* Example of os_circle() */ /* Change to screen mode 12 and draw circle of radius 300. */ #include "roslib.h" void main(void) os_mode(12); x = 500; y = 500; r = 300; os_circle(x, y, r); }

   Name    os_circlefill

   Syntax    os_error *os_circlefill(int x, int y, int r);

   Description    Draw a solid circle whose centre is at the coordinates specified by x and y , with a radius specified by r .

   Returns    A pointer to an error if one has occurred, or zero if the operation was successful. See page 124 for further details.

   Example    /* Example of os_circlefill() */ /* Change to screen mode 12 and draw solid circle of radius 300. */ #include "roslib.h" void main(void) os_mode(12); x = 500; y = 500; r = 300; os_circlefill(x, y, r); }

   Name    os_clg

   Syntax    os_error *os_clg(void);

   Description    Clear the graphics window to the current graphics background colour.

   Returns    Void.

   Example    /* Example of os_clg() */ /* Set up a graphics window (using os_vduq) then clear it to a specified background colour. */ #include "roslib.h" void main(void) os_vduq(24, 0, 1, 0, 1, 0, 2, 0, 2); os_gcol(0, 130); os_clg(); }

   Name    os_cli

   Syntax    os_error *os_cli(char *s);

   Description    Pass the string pointed to by parameter s to the command line interpreter to execute as a command. Please refer to your computer user guides for a list of commands available.

   Returns    A pointer to an error if one has occurred, or zero if the operation was successful. See page 124 for further details.

   Example    /* Example of os_cli() */ /* Execute the command '*Help'. */ #include "roslib.h" void main(void) os_cli(s); }

   Name    os_cls

   Syntax    os_error *os_cls(void);

   Description    Clear the text window to the text background colour, and moves the text cursor to its home position.

   Returns    Void

   Example    /* Example of os_cls() */ /* Set up a text window (using os_vduq) then clear to a specified background colour. */ #include "roslib.h" void main(void) os_vduq(28, 5, 20, 45, 5); os_colour(132); os_cls(); }

   Name    os_colour

   Syntax    os_error *os_colour(int c);

   Description    Set the text colour to the value c . If c is is the range 0 to 127, the text foreground colour is set. Adding 128 to this (i.e. 128 to 255), sets the text background colour.

   Returns    A pointer to an error if one has occurred, or zero if the operation was successful. See page 124 for further details.

   Example    /* Example of os_colour() */ /* Display text in all the colours available in a 256-colour screen mode (mode 15). */ #include <stdio.h> #include "roslib.h" void main(void) os_mode(15); for(i = 0; i <= 63; i++) printf("Colour %d\n", i); } }

   Name    os_cursor

   Syntax    os_error *os_cursor(int n);

   Description    Control the appearance of the cursor according to the value of n :

n    meaning 0    stops the cursor appearing 1    makes the cursor re-appear 2    steady cursor 3    flashing cursor

   Returns    A pointer to an error if one has occurred, or zero if the operation was successful. See page 124 for further details.

   Example    /* Example of os_cursor() */ /* Step through the four cursor types. */ #include <stdio.h> #include "roslib.h" void main(void) for(i = 0; i <= 3; i++) printf("Cursor %d\n", i); printf("Press any key to continue.\n"); os_get(); } }

   Name    os_draw

   Syntax    os_error *os_draw(int x, int y);

   Description    Draw a line in the current graphics foreground colour to the absolute coordinates specified by x and y .

   Returns    A pointer to an error if one has occurred, or zero if the operation was successful. See page 124 for further details.

   Example    /* Example of os_draw() */ /* Draw a series of steps using os_draw(). */ #include "roslib.h" void main(void) os_mode(12); x = y = 0; while(x <= 1280) os_draw(x, y += 32); } }

   Name    os_drawby

   Syntax    os_error *os_drawby(int x, int y);

   Description    Draw a line in the current graphics foreground colour to the position specified by the offsets x and y , relative to the current position.

   Returns    A pointer to an error if one has occurred, or zero if the operation was successful. See page 124 for further details.

   Example    /* Example of os_drawby() */ /* Draw series of steps using os_drawby(). */ #include "roslib.h" void main(void) os_mode(12); for(i = 1; i <= 32; i++) os_drawby(0, 32); } }

   Name    os_file

   Syntax    os_error *os_file(filestr *p);

   Description    Perform an OS_File SWI call, which performs actions on whole files. The parameter p points to a structure of type filestr , which passes various arguments to OS_File.

typedef struct 



  char *objname;

  int loadaddr;

  int execaddr;

  int startaddr;

  int endaddr;   

  int reserved[4]; 

} filestr;

   Returns    A pointer to an error if one has occurred, or zero if the operation was successful. See page 124 for further details.

   Example    /* Example of os_file() */ /* Create file "temp" in current directory and read it's catalogue information using OS_File 17. */ #include <stdio.h> #include "roslib.h" void main(void) os_cli("Create temp 100"); p.action = 17; p.objname = "temp"; os_file(&p); printf("Object type = %d\n", p.action); printf("Object name = %s\n", p.objname); printf("Load address = %X\n", p.loadaddr); printf("Exec address = %X\n", p.execaddr); printf("Obj length = %d\n", p.startaddr); printf("Attributes = %d\n", p.endaddr); }

   Name    os_fill

   Syntax    os_error *os_fill(int x, int y);

   Description    Flood-fill an area in the current foreground colour, commencing at the coordinates specified by the parameters x and y .

   Returns    A pointer to an error if one has occurred, or zero if the operation was successful. See page 124 for further details.

   Example    /* Example of os_fill() */ /* Draw a series of steps using os_drawby(), then fill above with red and below with green. */ #include "roslib.h" void main(void) os_mode(12); for(i = 1; i <= 32; i++) os_drawby(0, 32); } os_gcol(0, 1); os_fill(200, 500); os_gcol(0, 2); os_fill(500, 200); }

   Name    os_find

   Syntax    os_error *os_find(regset *r);

   Description    Perform an OS_Find SWI call to open and close files. The parameter r points to a structure of type regset , which contains an array of integers used to pass registers to OS_Find.

typedef struct 



} regset;

   Returns    A pointer to an error if one has occurred, or zero if the operation was successful. See page 124 for further details.

   Example    /* Example of os_find() */ /* Use OS_Find 0x83 to create file "temp" in current directory. Use OS_Find 0 to close it. */ #include "roslib.h" void main(void) int h; r.r[0] = 0x83; r.r[1] = "temp"; os_find(&r); h = r.r[0]; /* file handle in r.r[0] */ r.r[0] = 0; r.r[1] = h; os_find(&r); }

   Name    os_gbpb

   Syntax    os_error *os_gbpb(gbpbstr *p);

   Description    Perform OS_GBPB SWI call to read or write a group of bytes from or to an open file. The parameter p points to a structure of type gbpbstr , which passes various arguments to OS_GBPB.

typedef struct



  int handle;

  void *startaddr;

  int number;

  int pointer;

  int buf_len;

  char *wildcard;

  int reserved[3];

} gbpbstr;

   Returns    A pointer to an error if one has occurred, or zero if the operation was successful. See page 124 for further details.

   Example    /* Example of os_gbpb() */ /* Create file "temp" in current directory, write characters A to Z, and finally close file. */ #include "roslib.h" void main(void) os_gbpbstr p; int h; r.r[0] = 0x83; r.r[1] = "temp"; os_find(&r); h = r.r[0]; p.action = 2; p.handle = h; p.startaddr = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; p.number = 26; os_gbpb(&p); r.r[0] = 0; r.r[1] = h; os_find(&r); }

   Name    os_gcol

   Syntax    os_error *os_gcol(int a, int c);

   Description    Set the graphics plot colour and action. If c is is the range 0 to 127, the graphics foreground colour is set. Adding 128 to this (i.e. 128 to 255), sets the graphics background colour. The graphics plotting action is specified by a as follows:

a    action 0    plot colour on screen with c 1    OR colour on screen with c 2    AND colour on screen with c 3    EOR colour on screen with c 4    Invert colour on screen 5    Leave screen unchanged 6    AND colour on screen with inverse of c 7    OR colour on screen with inverse of c

If 16, 32, 48 or 64 is added to a , the first, second, third or fourth colour pattern respectively is used instead of c . Adding 80 causes all four patterns to be used, placed side-by-side.

   Returns    A pointer to an error if one has occurred, or zero if the operation was successful. See page 124 for further details.

   Example    /* Example of os_gcol() */ /* Plot a series of solid circles in different colours. */ #include "roslib.h" void main(void) os_mode(12); for(x = 0; x <= 1080; x += 180) os_circlefill(x + 100, 500, 85); } }

   Name    os_get

   Syntax    int os_get(void);

   Description    Return a character from the input stream. The function does not return until a character is available, thus halting the program temporarily.

   Returns    The ASCII code for the character in the input stream, or the value 0x1xx if an escape condition exists.

   Example    /* Example of os_get() */ /* Get character typed at keyboard and print ASCII code. Repeat until Esc pressed. */ #include <stdio.h> #include "roslib.h" void main(void) printf("Type characters now\n"); while((c = os_get()) != -27) printf("%d\n", c); }

   Name    os_inkey

   Syntax    int os_inkey(int n);

   Description    Return a character from the input stream. If n is a positive integer, it represents the time limit in centi-seconds. If n is a negative integer in the range -255 to -1, it represents the negative INKEY code of the key being interrogated. Please refer to your computer user guide for a list of negative INKEY values.

   Returns    If n is positive, it returns the ASCII code for the character in the input stream, or -1 if there is no character within the time limit.

If n is negative, it returns -1 if the interrogated key is being pressed, or 0 if not.

If n is -256, it returns the version of the operating system in use.

   Example    /* Example of os_inkey() */ /* Wait up to 5 seconds for a key to be pressed. If a key is pressed within the time limit, print it's ASCII value, otherwise print message "Timeout!". */ #include <stdio.h> #include "roslib.h" void main(void) printf("Press a key:\n"); k = os_inkey(500); if(k == -1) printf("Timeout!\n"); else printf("Key %d pressed.\n", k); }

   Name    os_mode

   Syntax    os_error *os_mode(int m);

   Description    Set the screen display to mode m .

   Returns    A pointer to an error if one has occurred, or zero if the operation was successful. See page 124 for further details.

   Example    /* Example of os_mode() */ /* Change to mode 15 and draw circle. */ #include "roslib.h" void main(void) os_circle(640, 512, 250); }

   Name    os_move

   Syntax    os_error *os_move(int x, int y);

   Description    Move the graphics cursor to the absolute coordinates specified by x and y .

   Returns    A pointer to an error if one has occurred, or zero if the operation was successful. See page 124 for further details.

   Example    /* Example of os_move() */ /* Draw a series of vertical lines using os_move() to position the graphics cursor for each new line. */ #include "roslib.h" void main(void) os_mode(12); for(x = 0; x < 1280; x += 32) os_draw(x, 1023); } }

   Name    os_moveby

   Syntax    os_error *os_moveby(int x, int y);

   Description    Move the graphics cursor to the position specified by the offsets x and y , relative to the current position.

   Returns    A pointer to an error if one has occurred, or zero if the operation was successful. See page 124 for further details.

   Example    /* Example of os_moveby() */ /* Draw five rectangles using os_moveby() to shift the graphics cursor after each. */ #include "roslib.h" void main(void) os_mode(12); for(x = 1; x <= 5; x++) os_drawby(100,0); os_drawby(0, -100); os_drawby(-100,0); os_moveby(150, 0); } }

   Name    os_origin

   Syntax    os_error *os_origin(int x, int y);

   Description    Set the graphics origin to the position specified by the absolute the offsets x and y . The graphics origin is the screen position of point (0, 0), and is used for all subsequent graphics output.

   Returns    A pointer to an error if one has occurred, or zero if the operation was successful. See page 124 for further details.

   Example    /* Example of os_origin() */ /* Draw circle in centre of screen by setting os_origin() to the screen centre, then drawing circle at coordinates 0, 0. */ #include "roslib.h" void main(void) os_origin(639, 511); os_circle(0, 0, 100); }

   Name    os_palette

   Syntax    os_error *os_palette(int l, int m, int r, int g, int b);

   Description    Define the colour palette, where l is the logical colour to set, m is the physical colour or mode, and r , g and b represent the red, green and blue colour information.

m    action 0-15    logical colour l = physical colour m ( r , g , and b are ignored) 16    logical colour l = physical colour specified by r , g , b 17    define first flash colour for l 18    define second flash colour for l 24    border colour = physical colour specified by r , g , b 25    mouse logical colour l = physical colour specified by r , g , b

   Returns    A pointer to an error if one has occurred, or zero if the operation was successful. See page 124 for further details.

   Example    /* Example of os_palette() */ /* Plot a solid circle in colour 1, then change the palette for colour 1 to a specified RGB value. */ #include <stdio.h> #include "roslib.h" void main(void) os_mode(12); os_gcol(0,1); os_circlefill(639, 511, 200); printf("Press a key to change palette\n"); os_get(); red = 120; green = 128; blue = 186; os_palette(1, 16, red, green, blue); }

   Name    os_plot

   Syntax    os_error *os_plot(int p, int x, int y);

   Description    Perform an operating system plot function. Parameters x and y are the screen coordinates, and p is the plot number. Please refer to your computer user guide for a list of plot numbers.

   Returns    A pointer to an error if one has occurred, or zero if the operation was successful. See page 124 for further details.

   Example    /* Example of os_plot() */ /* Change to screen mode 12 and plot a circle segment using os_plot() with plot number 173. */ #include "roslib.h" void main(void) os_move(750, 0); os_plot(173, 0, 750); }

   Name    os_point

   Syntax    int os_point(int x, int y);

   Description    Return the logical colour of the pixel at the coordinates specified by x and y .

   Returns    An integer in the range 0 to 63 representing the logical colour, or -1 if the specified point lies outside the current graphics window.

   Example    /* Example of os_point() */ /* Change to screen mode 12, draw solid circle and use os_point() to return the colour of the circle. */ #include <stdio.h> #include "roslib.h" void main(void) os_gcol(0, 3); os_circlefill(500, 500, 300); printf("Colr = %d\n", os_point(500, 500)); }

   Name    os_pos

   Syntax    int os_pos(void);

   Description    Return the X coordinate of the text cursor.

   Returns    An integer between 0 and the width of the current text window minus one.

   Example    /* Example of os_pos() */ /* Print some text then return X coordinate of the text cursor. */ #include <stdio.h> #include "roslib.h" void main(void) printf("Sample text."); x = os_pos(); printf("\nX coordinate = %d\n", x); }

   Name    os_rectangle

   Syntax    os_error *os_rectangle(int x, int y, int w, int h);

   Description    Draw the outline of a rectangle at the coordinates specified by x and y , with a width and height specified by w and h .

   Returns    A pointer to an error if one has occurred, or zero if the operation was successful. See page 124 for further details.

   Example    /* Example of os_rectangle() */ /* Change to screen mode 12 and draw a rectangle. */ #include "roslib.h" void main(void) os_mode(12); x = 300; y = 300; w = 600; h = 400; os_rectangle(x, y, w, h); }

   Name    os_rectanglefill

   Syntax    os_error *os_rectanglefill(int x, int y, int w, int h);

   Description    Plot a solid rectangle at the coordinates specified by x and y , with a width and height specified by w and h .

   Returns    A pointer to an error if one has occurred, or zero if the operation was successful. See page 124 for further details.

   Example    /* Example of os_rectanglefill() */ /* Change to screen mode 12 and draw a solid rectangle. */ #include "roslib.h" void main(void) os_mode(12); x = 300; y = 300; w = 600; h = 400; os_rectanglefill(x, y, w, h); }

   Name    os_rnd

   Syntax    unsigned os_rnd(int n);

   Description    Return a random number, or re-seeds the random number generator.

   Returns    If n is positive, it returns a random integer number between 0 and n-1.

If n is negative, it re-seeds the random number generator and returns 0.

   Example    /* Example of os_rnd() */ /* Print 100 random numbers between 1 and 100. */ #include <stdio.h> #include "roslib.h" void main(void) for(i = 1; i <= 100; i++) printf("%d\n", os_rnd(100) + 1); }

   Name    os_sound

   Syntax    os_error *os_sound(int c, int a, int p, int d);

   Description    Generate a sound. The parameters c , a , p , and d represent the channel, amplitude, pitch and duration.

   Returns    A pointer to an error if one has occurred, or zero if the operation was successful. See page 124 for further details.

   Example    /* Example of os_sound() */ /* Make a sound. */ #include "roslib.h" void main(void) }

   Name    os_swi

   Syntax    void os_swi(int n, regset *r);

   Description    Performs the SWI call specified by the parameter n . The parameter r points to a structure of type regset , which contains an array of integers used to pass registers to the SWI routine. If an error occurs, an operating system error is raised. Please refer to your Programmers Reference Manual for a complete list of SWI calls available.

typedef struct 



} regset;

   Returns    Void.

   Example    /* Example of os_swi() */ /* Call OS_ConvertHex2 to convert a decimal number to a 2-byte hex string. This example uses os_swi(), so if an error occurs it is raised by the operating system automatically. */ #include <stdio.h> #include "roslib.h" #include "swis.h" void main(void) int d; char s[3]; d = 255; r.r[0] = d; r.r[1] = s; r.r[2] = 3; os_swi(OS_ConvertHex2, &r); printf("%d in hex = %s", d, r.r[0]); }

   Name    os_swix

   Syntax    os_error *os_swix(int n, regset *r);

   Description    Performs the X form of the SWI call specified by the parameter n . The parameter r points to a structure of type regset , which contains an array of integers used to pass registers to the SWI routine. If an error occurs, a pointer to the error is returned; an operating system error is not raised. Please refer to the Programmers Reference Manual for a complete list of SWI calls available.

typedef struct 



} regset;

   Returns    A pointer to an error if one has occurred, or zero if the operation was successful. See page 124 for further details.

   Example    /* Example of os_swix() */ /* Call OS_ConvertHex4 to convert a decimal number to a 4-byte hex string. This example uses os_swix(), so if an error occurs it may be trapped and reported by this program. */ #include <stdio.h> #include "roslib.h" #include "swis.h" void main(void) os_error *e; int d; char s[5]; d = 65535; r.r[0] = d; r.r[1] = s; r.r[2] = 5; e = os_swix(OS_ConvertHex4, &r); if(e) printf("E%d%s\n", e->errnum, e->errmess); else printf("%d converted to hex = %s", d, r.r[0]); }

   Name    os_tab

   Syntax    os_error *os_tab(int x, int y);

   Description    Position the text cursor at the coordinates specified by x and y . both coordinates must lie within the current text window, otherwise no cursor movement will take place.

   Returns    A pointer to an error if one has occurred, or zero if the operation was successful. See page 124 for further details.

   Example    /* Example of os_tab() */ /* Print the horizontal tab position at every 8 characters across the screen. */ #include <stdio.h> #include "roslib.h" void main(void) os_mode(12); for(x = 0; x <= 72; x += 8) printf("%d", x); } }

   Name    os_tint

   Syntax    os_error *os_tint(int c, int t);

   Description    Set the tint for a colour. The parameter c specifies which colour is set, as follows:

c    colour 0    text foreground colour 1    text background colour 2    graphics foreground colour 3    graphics background colour

The parameter t specifies the level of tint required, as follows:

t    tint 0x00    darkest 0x40    dark 0x80    light 0xC0    lightest

Returns a pointer to an error if one has occurred, or zero if the operation was successful. See page 124 for further details.

   Example    /* Example of os_tint() */ /* Plot a solid circle in 4 tints. */ #include "roslib.h" void main(void) os_mode(15); os_gcol(0, 25); for(t = 0; t <= 3; t++) os_circlefill(500, 500, 200 - t * 50); } }

   Name    os_vpos

   Syntax    int os_vpos(void);

   Description    Return the Y coordinate of the text cursor.

   Returns    An integer between 0 and the depth of the current text window minus one.

   Example    /* Example of os_vpos() */ /* Print some lines of text then return Y coordinate of the text cursor. */ #include <stdio.h> #include "roslib.h" void main(void) for(i = 0; i <= 8; i++) printf("Line %d\n", i); y = os_vpos(); printf("\nY coordinate = %d\n", y); }

   Name    os_vdu

   Syntax    os_error *os_vdu(int c);

   Description    Send the single byte c to the VDU drivers. Please refer to your computer user guide for a list of VDU commands.

   Returns    A pointer to an error if one has occurred, or zero if the operation was successful. See page 124 for further details.

   Example    /* Example of os_vdu() */ /* Plot a circle segment using the os_vdu() function to send the single bytes to the vdu drivers. See also os_vduq() and os_vduw(). */ #include "roslib.h" void main(void) os_move(750, 0); os_vdu(25); os_vdu(173); os_vdu(0); os_vdu(0); os_vdu(238); os_vdu(2); }

   Name    os_vduq

   Syntax    os_error *os_vduq(int c, ...);

   Description    Send multiple bytes to the VDU drivers. The number of bytes sent is appropriate to the the VDU command c , and the function assumes the correct number of parameters have been passed. Please refer to your computer user guide for a list of VDU commands, and the number of parameters for each command.

   Returns    A pointer to an error if one has occurred, or zero if the operation was successful. See page 124 for further details.

   Example    /* Example of os_vduq() */ /* Plot a circle segment using the os_vduq() function to send multiple bytes to the vdu drivers. See also os_vdu() and os_vduw(). */ #include "roslib.h" void main(void) os_move(750, 0); os_vduq(25, 173, 0, 0, 238, 2); }

   Name    os_vduw

   Syntax    os_error *os_vduw(int w);

   Description    Send the word w to the VDU drivers as a pair of bytes (low byte first).

   Returns    A pointer to an error if one has occurred, or zero if the operation was successful. See page 124 for further details.

   Example    /* Example of os_vduw() */ /* Plot a circle segment using the os_vduw() function to send the required words to the vdu drivers. See also os_vdu() and os_vduq(). */ #include "roslib.h" void main(void) os_move(750, 0); os_vdu(25); os_vdu(173); os_vduw(0); os_vduw(750); }

   Name    os_word

   Syntax    os_error *os_word(int a, void *p);

   Description    Perform an OS_Word SWI call. Parameter a is the reason code which determines the action of the call, and parameter p pointing to a parameter block which is passed to register R1. Often the first byte of the parameter block contains a sub-reason code. Please refer to your computer user guides for a list OS_Word reason codes and parameters.

   Returns    A pointer to an error if one has occurred, or zero if the operation was successful. See page 124 for further details.

   Example    /* Example of os_word() */ /* Use OS_Word call 14,0 to read CMOS clock, then print the result. */ #include <stdio.h> #include "roslib.h" void main(void) int i = 0; p[0] = 0; os_word(14, p); while(p[i] != 13) printf("%c", p[i++]); }

T he Easy C debugger, !EasyDebug provides an easy-to-use yet powerful system for debugging C programs. With this latest release, full StrongARM compatability has been achieved!

The following features are provided:

l Source and object-level debugging i.e. by line of C source or by ARM instruction.

l Run, Stop, Continue and Single step programs.

l Source listing including powerful Find facility. Display source with memory address of code.

l Stack trace showing functions called to reach current line. Options to step up and down the function stack.

l Display local and global variables available at current line. Edit values of variables. Expand pointers, structures and unions. Expression evaluator.

l Set and unset Breakpoints. Update variable value on breakpoint (watchpoint). Conditional breakpoints. Breakpoints can execute simple functions. Save breakpoints.

l Memory editor with various display modes. Show register values.

l Profiling facility displays time taken to execute functions. There are a number of limitations with WIMP programs - see later.

Getting started

To use the debugger you must first compile your program using the debug option provided in the Easy C setup dialogue box. An example program DebugEx is supplied in directory Programs.General.c . This comprises two source files, DebugEx1 and DebugEx2 .

Load Easy C and drag both these source files to the source window, ensuring it is cleared of all previous files. Open the Setup dialogue box by choosing Setup from the main menu or by pressing F5. Now select the option Debug and deselect the option Peephole .

Peephole optimisation is deselected because it removes stack frames and can cause the debugger to give misleading information. You can still debug a program with peephole optimisation, but some function calls might me misleading.

Click on Compile to compile the source files. Please note that when the Debug option is selected, Easy C generates debug files in subdirectory debug . An error will be given if this directory doesn't exist.

When compilation is complete, click on Link to generate the executable program. The executable program with debug code is given a special filetype and icon.

Source level or object level debugging

Normally you should compile and link your programs with the Debug option enabled. This allows you to debug your programs at source level i.e. you will be able to see the lines of C source code in the debugger and single step through them, set breakpoints at them etc.

If the Debug option is enabled for linking but disabled for compiling, you will only be able to use the debugger at object level i.e. you will only be able to single step, set breakpoints etc. at object code level.

If the Debug option is disabled for linking as well, you will not have access to function names.

When debugging at object level, the operation of the debugger changes as follows:

1.    The debugger starts automatically in the memory editor. 2.    The memory editor is set to Code mode and is Active . 3.    Single stepping can only be set to Instruction .

Running the debugger

Double-click on the executable file DebugEx1 to run the debugger, or run the debugger and drag DebugEx1 to the icon bar icon. Two windows are displayed; one is the main debugger window shown below, and the other is a task window which displays any textual output from the program and accepts any textual input from the user.

Please note that you must have a copy of Edit (or any task window provider) loaded. If you have compiled your program using peephole optimisation, a warning will be given at this stage (see previous page). You will also be warned if insufficient memory for your program has been allocated for the wimpslot (see page 221).

The main debugger window contains three separate 'panes'.

Source files

This pane lists the sources files for the current program which were compiled using the Debug option.

Stack trace

This displays a traceback of the program's stack. It will be blank until the program has been run and subsequently stopped.

Breakpoints

This lists the breakpoints that are set. At this stage it will be blank.

Running the program

The debugger is now in the 'idle' state and the options listed below are available. The function key presses shown next to each command below may be used if the main debugger window has the input focus.

Run (F1)

Click on Run to run the program. This example program is a simple loop which increments a variable, calls a function and prints the result. The values printed are displayed in the task window. The writable icon next to Run may be used to pass command line arguments to the program.

Stop (F2)

Click on Stop to stop the program that is running. When the program stops, the following things occur:

1. The Source files pane shows the current source file indicated with a tick. The current source file is the file in which the program was stopped. The Source listing window is opened listing the current source with the current line highlighted. The current line is the line at which the program was stopped.

2. The Stack trace pane is updated with a traceback of the program's stack. The current function is indicated with a tick. The current function is the function in which the program was stopped.

3. The Variable list window is displayed, listing the local and global variables active at the current line. Any variables in the Variable values window are updated.

When a program has stopped, you can do one of the following:

Cont (F3)

When the program has been stopped (either by the Stop button or by a breakpoint or when single stepping), the Cont button causes program execution to continue. Note that the Variable list window automatically closes. Step (F4)

When the program has been stopped (either by the Stop button or by a breakpoint), the Step button causes the the debugger to single step the program. It steps one line (or one ARM instruction if required�see main menu options) and follows function calls.

After each step the program is stopped and the source, stack trace and variables windows are all updated as describe d for Stop above.

Next (F5)

Click on Next to step to the next source line. As Step above, but any function calls are skipped over. Any breakpoints within the functions skipped, are not activated. Note that although the debugger skips the function calls, the functions are still executed.

Status information

The title bar displays the current debugger State. The possible states are:

Idle      The program has not yet been run.

Running    The program is running

Stopped    The program has been stopped either by the Stop button or      by a breakpoint.

Aborted    The program has stopped in such a way that the user cannot      Cont . This may be due to a programming error or at the end      of the program.

Complete    The program has exited.

The letter in brackets after the state indicates whether the debugger is in Line (L) or Instruction (I) mode when single stepping. In Line mode the debugger steps an entire line of source code; in Instruction mode the debugger steps a single ARM instruction. This mode can be changed from the main debugger menu option Step , or with the keypress Ctrl S.

Source files pane

The small pane labelled Source files in the top left corner of the main debugger window lists the source files present in the program.

Only source files for which there is an associated debug file are displayed. This means that a source file must have been compiled using the Debug option enabled in Easy C.

If you click Select on a source file, a tick will appear next to it and the Source listing window is opened containing a listing of the source file. There can only be one Source listing window at any one time, so choosing another source replaces the previous one.

Click Menu over a source file to display the source files menu.

File

This option displays a dialogue box giving information about the specified source file i.e. the source file over which Menu was clicked.

Path is the full pathname of the source file.

Type is the file type of the source file (usually Text).

Language is the language that the source file was written in. Currently this can only be C.

Size is the size of the source file in bytes.

Symbols is the number of symbols contained in the file.

Optimise indicates whether the program was optimised when compiled.

Profile indicates whether profiling was enabled when the program was compiled. Find

This options allows you to search all the source files in the source file pane for the name of a function.

Type the name of the function you wish to find in the box labelled Find , or click on Previous to display the last function searched for. Now press Return or click on Find to locate the first occurrence of the function name. If the function name is found, the relevant line is highlighted in the source listing window and the Found dialogue box is displayed. If the function name cannot be found, a beep is sounded.

Click on Next to find the next occurrence of the function name, or Previous to find the last occurrence. A beep is sounded if no more occurrences can be found.

By default the find facility makes no distinction between upper and lower case characters, but you can specifically request it to match case by clicking on Case sensitive .

If Regular expressions is selected, the find facility supports a limited form of regular-expression notation. A regular expression specifies a set of character strings to match against - such as "any string containing digits 5 through 9" or "only lines containing uppercase letters." A member of this set of strings is said to be matched by the regular expression.

Full details of regular expressions are given towards the end of this section.

Source listing window

This window is opened when you choose a source file from the Source files pane in the main debugger window. It is used for display purposes only�you cannot edit the source file. When the debugger is in the 'stopped' state, the line at which the program was stopped is highlighted in this window.

You may set and unset breakpoints by double-clicking Select over the required lines. A bullet character is displayed at the start of a line to confirm a breakpoint is set.

Click Menu over the window to display the following menu.

Display

This option provides a submenu with two options. If Line numbers is selected, each line of the source code is given a line number. If Addresses is selected, each line of the source code is given the address at which the compiled code is located. You can use the memory editor (described later) to examine the code at any address.

Find

Find allows you to search for an object in the source code. Please refer to page 203 for details of how to use Find .

Clear breakpoints

Clears all the breakpoints in the source file. This operation cannot be undone.

Automatic

If Automatic is selected, the debugger will automatically open the Source listing window whenever a program is stopped. If Automatic is not selected, and the window is closed using the close icon, it will remain closed unless reopened from the Open window option on the main debugger menu.

Stack trace

The Stack trace window shows a traceback of the program's stack. It is updated each time the program is stopped (either by the Stop button or by a breakpoint or when single stepping).

The first function in the stack trace window is the function at which the program was stopped. Each subsequent function is the 'calling' function. The final function in the stack trace window is main .

You can click on any function in the list to go to that function. Alternatively you may step up and down the stack using the buttons Up and Down . Click on Up to step up the stack i.e. down the stack trace window towards main . Click on Down to move down the stack i.e. up the stack trace window.

Clicking on a function or using Up and Down automatically places a tick next to the chosen function, and updates the source and variable windows.

The stack trace facility allows you to easily step from any line in a program to the calling function, and so on until you reach the main() function. At each stage the variables that are declared and the values of those variables can be examined.

Note �When single stepping into a function, the debugger stops at the first instruction of the function. This is before the program has built a new stack frame entry for the function so the stack trace cannot be relied upon until the user has actually entered the function. What the stack trace window will display is the name of the current function (the one being stepped into) at the top of the window followed by the function that was second on the stack. By clicking Step again, the stack trace is corrected.

Variables

The Variable list window is displayed whenever the program is stopped (either by the Stop button or by a breakpoint or when single stepping). It is also displayed whenever you change function in the Stack trace window. The Variable list window is always automatically closed when the program is running.

The Variable list window lists the global and local variables available to the user at the point that the program stopped. The global variables include those which are available everywhere in the program ( extern ) and those which are only available in the current file. The local variables are those which are only available in the current function.

You can display the values of any variables by simply clicking on them. They become ticked, and the Variable value window is opened showing the values of the variables selected.

The Variable value window may be left open at all times, and will be updated every time the program is stopped. If you wish to remove a variable from this window, click on its name in the Variable list window to remove the tick.

If the variable is an unstructured type, you can change its value by clicking on the value in Variable value window to display the caret. The value may then be edited, and the change committed by pressing Return.

Expanding structures and pointers

If the variable in the Variable value window is a structure or pointer, it can be dereferenced further by double-clicking on its name. If the variable is a structure, it will be 'opened' and further details displayed. If the variable is a pointer, the value to which it points will be displayed. You can double-click Select on an open variable to close it again.

If the variable is an array of unstructured types, it will be displayed in its entirety. If the variable is an array of structured types, it will be displayed one element at a time. You can change the element displayed by clicking on the index value (between [ and ]) and editing it. Then press Return to reopen the array at the correct index. You may also edit the value of the array element.

Expression evaluation

The icon at the bottom of the Variable list window may be used to evaluate an expression. The result is displayed in the Debug output window which is normally opened automatically when anything is output.

To evaluate an expression, type it into the icon and press Return. The expression can use any of the variables in the window and a range of operators. Please refer to the section Expressions found towards the end of this chapter for more details.

This option is useful if you want to view a complete structure or array on one go, or to look at the contents of a pointer.

Expressions are buffered so that you can return to earlier expressions without having to type them in again. EasyDebug does not buffer an expression if it is identical to previous expression in the buffer.

If you click Menu over the Expression icon a menu of the last 20 expressions is displayed. Click Select on an expression to evaluate it.

Alternatively, clicking in the Expression icon so that it has the caret, allows you to step to other expressions in the buffer using the up and down arrows. When you have found the one you require, press Return to evaluate it (editing it first if you wish). Variable list menu

Click menu over a variable to display the following menu.

Variable

This displays a dialogue box displaying information about the chosen variable i.e. the variable over which Menu was clicked.

Name is the full name of the variable (it may have been abbreviated in the menu)

Type is the type of the variable.

If the variable is a structure, Tag is the tag of the structure.

Size is the size of the variable in bytes

Storage indicates where the variable is stored. It may be stack , register or static .

Address / Register is the address of the variable or the name of register in which it is stored.

Find

This option allows you to search for variables in the list. When found, the variable and its value is displayed in the Debug output window. Please refer to page 203 for general details of how to use Find .

Automatic

If this option is selected, the debugger will automatically open the Variable list window whenever a program is stopped. If Automatic is not selected, and the window is closed using the close icon, it will remain closed unless reopened from the Open window option on the main debugger menu.

Debug output

The Debug output window is used by the debugger to display information requested by the user. This can either be the value of expressions evaluated in the Variable list window, or the output from the printf function which has been executed at a breakpoint.

Click Menu over the window to display the following menu.

Clear

This option clears the text from the window.

Save

This option saves the contents of the window as a text file using the standard save box.

Find

This option allows you to search for text in the window. Please refer to page 203 for general details of how to use Find .

Automatic

If this option is selected, the debugger will automatically open the Debug output window whenever something is output into it. If Automatic is not selected, and the window is closed using the close icon, it will remain closed unless reopened from the Open window option on the main debugger menu.

Breakpoints

The Breakpoints pane in the centre of the main debugger dialogue box displays a list of currently active breakpoints. These are set by double clicking in the Source listing window or by using the Set option described below.

By default the program will stop when it reaches one of the set breakpoints, allowing you to examine the variables available. Afterwards you may continue running the program or single step from the breakpoint. A breakpoint is implemented by replacing one of the program instructions by a special instruction which causes the program to stop. A breakpoint is always set at an address in the program space.

Each line in the breakpoint pane corresponds to one breakpoint, and gives the following information:

1.    The address at which the breakpoint was set.

2.    The file in which the breakpoint was set.

3.    The line at which the breakpoint was set.

4.    The function in which the breakpoint was set.

You may select breakpoints for editing and deletion. To select a single breakpoint, click Select over it (this removes any existing selection). To select a group of breakpoints, click Select over the first one, and Adjust on each of the others in turn. Use Adjust to deselect breakpoints.

Click menu over the breakpoint pane to display a menu which provides various options for editing the selected breakpoints. If there is no selected breakpoint, the menu options will apply to the breakpoint under the pointer. Breakpoint 'brk_0'

If there is a single breakpoint selected, this option provides a submenu of options for manipulating the specified breakpoint.

If there is more than one breakpoint selected, this option changes to Selection and provides a submenu of options affecting all the selected breapoints.

Each time a breakpoint is created it is given a 'tag' which acts like a global integer variable to the debugger, and can be given a value . The tag is of the form brk_n , where n is a numeric value which is incremented for each subsequent breakpoint created e.g. brk_0 , brk_1 , brk_2 etc.

Edit

This option provides a dialogue box allowing the behaviour of the breakpoint to be changed. This option is not available if there is a selection of breakpoints.

Tag is the tag name for the breakpoint. Each breakpoint is given a default name of the form brk_n , but this may be changed to any name you choose.

Value is the value of the tag. By default it is set to 0, but it may be given any integer value.

If Stop is selected the program will be stop when the breakpoint is activated; this is the normal situation. If Stop is not selected, the program will not stop when the breakpoint is activated . However, the Variable value window will be updated each time the breakpoint is activated. this allows you to monitor the value of any variables in this window without stopping the program. A breakpoint set in this way is often called a Watchpoint .

If Exec before is selected, the code in the writable icon will be executed when the breakpoint is reached, but before any conditional check is made (see overleaf). The executable code allows variables and breakpoint tags to be set, and their values printed.

A variable is set using the set statement:

set count = count + 1

A v ariable is printed using the printf statement following the standard C format:

printf("variable x = %d\n", x)

The output is displayed in the Debug output window, which will normally open automatically for the output.

A number of statements can be executed by separating them with semicolons:

set brk_0=brk_0 + 1;printf(x = %d\n", x)

If Conditional is selected, the breakpoint reached will only be activated if the condition evaluates to True (non zero). In which case the Stop option determines whether the program is stopped. If the condition is False, the program continues running, ignoring the breakpoint. If Conditional is not selected, any breakpoints reached will always be activated.

The conditional expression may contain both variables and breakpoint tags. Examples:

brk_0 == 100

If Exec after is selected, the code in the writable icon will be executed only after a conditional breakpoint has evaluated to True. The format of the code is the same as for Exec before .

Conditional , Exec before and Exec after may be used together to good effect. The following breakpoint settings, will cause the breakpoint whose tag is brk_0 to become activated the fourth time it is reached. The value of the variable x is then printed.

Exec before:    brk_0 = brk_0 + 1

Conditional:    brk_0 == 4

Exec after:    printf("Variable x = %d", x)

Clear

This option permanently removes the selected breakpoints.

Ignore

This option causes the selected breakpoints to be temporarily suspended. Ignored breakpoints are shaded in the breakpoint pane, and can be resumed by clicking Ignore again.

Select all

This option selects all breakpoints.

Clear selection

This option clears the current selection.

Save

This option saves the current breakpoints to a text file using the standard save box. The saved file can be reloaded at any time by dragging it into the breakpoints pane.

Reloading a breakpoints file sets the breakpoints in the file being debugged. This is useful to preserve the breakpoint states over a number of runs of the debugger, and saves them having to be reset each time. This is only possible if the source files have not changed. An error is given if you update your source files and then attempt to load an old breakpoints file.

Set

This opens a dialogue box allowing a breakpoint to be set. Normally breakpoints are set by double clicking on the required line the Source listing window. However, this menu allows the user to have a lower level control over setting breakpoints.

Choose At function to set a breakpoint at the first instruction of the function specified in the writable icon.

Choose At address to set a breakpoint at the address specified in the writable icon (in hex).

Choose At line to set a breakpoint in the specified file, at the specified line.

Auto load

If this option is selected, the debugger will automatically attempt to load a breakpoint file when it is run. This saves having to load a breakpoint file by dragging to the breakpoint pane. The breakpoint file must be called BrkPoints , and should reside in the same directory as the executable file being debugged.

The Profiler

This powerful facility allows you to obtain an execution profile of the program while it is running. The profile is a sorted table showing the time taken for functions to execute. Using this information if may be possible to improve the performance of your programs. This profiler is function based only i.e. it reports the time taken for functions to execute.

To use the profiler you must compile your programs using the Profiling/Function option on the Easy C Setup dialogue box. If some files are compiled with profiling on and some with it off, only those with it on will be profiled.

If your program was compiled with profiling enabled, the window shown below will be displayed when you run the program in the debugger.

Each line in the window corresponds to one function, and gives the following information:

%time percentage of the total time spent in this function

calls number of calls to this function

time average time spent in a call to this function in centi-secs

total total time spent in this function in centi-seconds

function function name

Click Menu over the profiler window to display the profiler menu.

Save

This option saves the profile information in CSV format suitable for export to other applications.

Display

This option opens the following dialogue box which allows the profile display to be modified.

Sort by allows you the choose the sorted order of the functions in the profiler display.

Refresh rate is the rate in seconds at which the profile display is updated.

Number of lines is the number of lines in the profile display. It is used to limit the size of the profile.

Find

This option allows you to search for a function in the profile. When found the profile display is scrolled until the function is visible. Please refer to page 203 for general details of how to use Find .

Stop

This option suspends the profile.

Continue

This options continues the profile after it has been suspended using Stop .

Main menu options

Click Menu over the main debugger window (not over the Source files, Stack trace panes or breakpoints), to display the main menu.

Open window

This displays a submenu from which all the debugger windows can be opened.

Normally, all the windows are opened automatically when required. The options described below are useful if any of the windows have been closed, and the Automatic option for the window is not enabled.

The Memory editor is described fully overleaf.

The Variable list and Variable values windows can only be opened if the program has been run and stopped (either by Stop or by a breakpoint).

Profile opens the Profile window. This window is normally opened when the program is loaded. The Profile window can only be opened if the program has been compiled using the Profiling option.

Source opens the Source listing window for the source file that is ticked in the Source files pane.

Debug output opens the window in which the debugger displays various information.

Info

This option opens a dialogue box giving information about image being debugged.

Step

This option opens a submenu allowing you to choose the step size when single stepping.

Line causes the debugger to single step one C source line at a time. Instruction causes the debugger to single step one ARM instruction at a time.

Memory editor

The memory editor is an extremely powerful window allowing the user to examine and modify memory and registers of the program being debugged. It should only be used by experienced users as it has the potential to corrupt the program environment.

The window consists of a register list and a scrolling pane. The register values are displayed in writable icons and are in hex. You can modify these by clicking on them, getting a caret, editing the value and pressing return. Any register may be modified including the program counter, frame pointer and stack pointer (THIS IS DANGEROUS).

Below the register list is a display of the 4 status flags of the processor. These are writable and take immediate effect (THIS IS DANGEROUS) .

The options ARM and APCS-R control how the register display and disassembly are shown. In ARM mode the registers are displayed as R0-R15 . In APCS (ARM Procedure Calling Standard - RISCOS) mode the names of the registers are a1-a4 , v1-v6 , sl , fp , ip , sp , lr , pc . This applies to the disassembly listing as well.

The scrolling pane contains the memory dump. This can be scrolled to display all of the memory allocated to the program being debugged. The display mode can be modified from the menu option Mode :

Word displays memory in 4 byte words (16 bytes per line)

Text displays memory in text format (32 bytes per line)

Byte displays memory in byte format (16 bytes per line)

Code displays memory in disassembled instruction format

If the mode is set to Word or Byte , the memory may be modified by clicking on the word or byte to modify, editing it and pressing Return.

If the mode is Code , a breakpoint may be set by double clicking on the address field.

Memory editor menu options

Follow

In Word mode, if the pointer is placed over an address value, clicking on Follow will display memory at the address under the pointer.

In Code mode, if the pointer is placed on a branch instruction, clicking on Follow will display code at the branch address.

Push, Pop

The Push and Pop options operate on a stack basis. Push works like Follow except that it pushes the address currently displayed on a stack. The address may be redispayed by clicking on Pop . This is useful for temporarily following a pointer or a BL instruction.

Goto

This option allows the dump to be moved to a particular address specified in hex.

Set memory

The Set memory option opens the dialogue box shown below and allows a range of memory to be set to a value.

Start address and End address specify the range of memory to be set to Value . If Word is not selected, each byte in the range is set to the value specified. If Word is selected, each word in the range is set to the value specified. The value should be in decimal unless preceded by & in which case it should be in hex.

Automatic

This option causes the debugger to automatically open this window when the program has stopped.

Active

This option makes the memory editor active. This means that it will keep up to date with the activities in the program being debugged. What this means depends on the mode of the dump window. If the mode is Code , then the display will show the last 2 instructions to be executed by the program. This is useful for single stepping instructions. The current instruction is displayed in black and the last executed instruction in grey.

If the mode is not Code , then the dump will be refreshed every time the program stops. This is useful for watching an area of memory for changes.

Refresh

This option refreshes the dump window and makes it up to date.

Icon bar menu

Click Menu over the EasyDebug icon bar icon to display the icon bar menu.

Info displays a dialogue box giving information about the version of EasyDebug you are using. Please quote the version number given in any correspondence with the publisher about Easy C++.

WimpSlot allows you to allocate memory from the WimpSlot for the program you are debugging. If there is insufficient memory, a warning will be given.

Save choices saves various settings in the debugger so that they are used automatically next time it is run. Settings saved include the automatic status of windows and the single step mode.

Quit , exits EasyDebug application, but not the debugger module.

Expressions

Expressions may be used in the Variables list window and the breakpoint Edit dialogue box.

Variable list window

The Expression icon allows you to type an expression to be evaluated and displayed in the Debug output window. If the expression is an aggregate type (struct/union or array) the whole value is printed. If the expression is a 'pointer to char' or an 'array of char', the value is printed as a character string. Only variables in the current scope may be printed, including local variables in the current function, static variables in the current file, and global variables in other files. Examples:

     count        an integer      count * 2      multiplication      my_struct      a structure      my_struct.start    a struct member

Breakpoint Edit dialogue box

In the breakpoint Edit window expressions may be used in the Condition icon and in the Exec before and Exec after icons.

Condition expressions evaluate to an integral value. If this value is non-zero then the condition is said to be True. Condition expressions will usually involve relational operators such as ==, >, < etc.

Exec before and Exec after expressions can contain the commands set and printf to change the value of a variable and print out values respectively. There may be multiple expressions in the code separated by semicolons.

The syntax of the set command is:

     set <expression> = <expression>

The left expression must be an lvalue (must have an address) and the right expression must match the type.

The printf command is similar to the C run time library call.

     printf ( <format-string> )

The format string contains the normal conversion characters ( %d , %x , %e , etc) but only the simple form is supported. This means that you cannot do things like %-12.4f .

One extension to the normal C printf is the %t format which says to print the struct or array in the expanded form (like the expression in the variables list window).

The output from the printf is to the debug output window.

In these expressions, the 'tag' of a breakpoint may be used as a local integer variable.

Examples:

Conditions:      fred == 4      count < 10      brk_0 > 5

Exec before and Exec after:      set brk_0 = brk_0 + 1      printf("The value is %d\n", ptr->count)      printf("%d\n",brk_1) ; set brk_1 = brk_1 * 2

Syntax of expressions

The syntax of supported expressions in BNF is:

procedure ::= statement | procedure ";" statement

statement = "set" expression "=" expression | "printf" "(" string ")"

expression = logical_or

logical_or = logical_and | logical_or "||" logical_and

logical_and = bitwise_or | logical_and "&&" bitwise_or

bitwise_or = exclusive_or | bitwise_or "|" exclusive_or

exclusive_or = bitwise_and | exclusive_or "^" bitwise_and

bitwise_and = equals | bitwise_and "&" equals

equals = relational | equals "==" relational | equals "!=" relational

relational = shift | relational "<" shift | relational ">" shift | relational "<=" shift | relational ">=" shift

shift = add_sub | shift ">>" add_sub | shift "<<" add_sub

add_sub = mult_div | add_sub "+" mult_div | add-sub "-" mult_div

mult_div = unary | mult_div "*" unary | mult_div "/" unary | mult_div "%" unary

unary = "*" unary | "&" unary | "!" unary | "-" unary | "~" unary | array_struct

array_struct = primary | primary "[" expression "]" | primary "." identifier | primary "->" identifier

primary = "sizeof" "(" expression ")" | "sizeof" primary | identifier | integer | floating | "(" expression ") "

Regular expressions in Find

Regular expressions (RE's) are built from the following single-character RE's:

c    Any ordinary character not listed below matches itself.

\    Backslash. When followed by a special character, the RE matches the "quoted" character. A backslash followed by one of < , > , ( , ) , } , represents an operator in a regular expression, as described below.

.    Dot. Matches any single character except NEWLINE.

^    As the leftmost character, a caret (or circumflex) constrains the RE to match the leftmost portion of a line. A match of this type is called an "anchored match" because it is "anchored" to a specific place in the line. It loses its special meaning if it appears in any position other than the start of the RE.

$    As the rightmost character, a dollar sign constrains the RE to match the rightmost portion of a line. The $ character loses its special meaning if it appears in any position other than at the end of the RE.

\<    This sequence constrains the one-character RE immediately following it only to match something at the beginning of a "word"; that is, either at the beginning of a line, or just before a letter, digit, or underline and after a character not one of these.

\>    This sequence constrains the one-character RE immediately following it only to match something at the end of a "word."

[c...] A non-empty string of characters, enclosed in square brackets matches any single character in the string. For example, [abcxyz] matches any single character from the set abcxyz . When the first character of the string is a caret ( ^ ), then the RE matches any character except NEWLINE and those in the remainder of the string. For example, [^45678] matches any character except 45678 . A caret in any other position is interpreted as an ordinary character. []c...] The right square bracket does not terminate the enclosed string if it is the first character (after an initial ^ , if any), in the bracketed string. In this position it is treated as an ordinary character.

[l-r] The minus sign, between two characters, indicates a range of consecutive ASCII characters to match. For example, the range [0-9] is equivalent to the string [0123456789] . Such a bracketed string of characters is known as a character class. The - is treated as an ordinary character if it occurs first (or first after an initial ^ ) or last in the string.

d    Delimiter character. The character used to delimit an RE within a command is special for that command (for example, see how / is used in the g command, below).

The following rules and special characters allow for constructing RE's from single-character RE's:

A concatenation of RE's matches a concatenation of text strings, each of which is a match for a successive RE in the search pattern.

*    A single-character RE, followed by an asterisk ( * ) matches zero or more occurrences of the single-character RE. Such a pattern is called a closure. For example, [a-z][a-z]* matches any string of one or more lower case letters.

\ A one-character RE followed by \ , \ , or

\ \ is an RE that matches a range of occurrences

\ of the one-character RE. The values of m and n must be non-negative integers less than 256; \ matches exactly m occurrences; \ matches at least m occurrences; \ matches any number of occurrences between m and n , inclusively. Whenever a choice exists, the RE matches as many occurrences as possible.

\(...\) An RE enclosed between the character sequences \( and \) matches whatever the unadorned RE matches, but saves the string matched by the enclosed RE in a numbered substring register. There can be up to nine such sub-strings in an RE, and parenthesis operators can be nested.

\n    Match the contents of the n th substring register from the current RE. This provides a mechanism for extracting matched substrings. For example, the expression ^\(..*\)\1$ matches a line consisting entirely of two adjacent non-null appearances of the same string. When nested parenthesized substrings are present, n is determined by counting occurrences of \( starting from the left.

//    The null RE ( // ) is equivalent to the last RE encountered.

Limitations

EasyDebug is a fully functional debugger. When debugging normal (non WIMP) programs it operates exactly as expected. However, when debugging WIMP programs it must interact with the program and the Desktop. The RISC OS WIMP has not been designed to cope with stepping through a running program. This is evident by observing the restrictions on calling Wimp_Poll in certain circumstances. For example, when output is directed to a sprite, or in the middle of a message sequence requiring acknowledgement.

The debugger works by controlling the program being debugged by a series of commands. The program being debugged is running in a TaskWindow and therefore a simple non WIMP program may multitask. As with all WIMP based programs, the debugger gains control of the processor when other programs call Wimp_Poll. This is the only way that this can happen. So, when the program being debugged is in a stopped state (say at a breakpoint, or during single stepping), the taskwindow is continually calling Wimp_Poll, allowing other tasks to run, including the debugger which may send further commands to it.

When debugging a WIMP program, this action of calling Wimp_Poll when the program has stopped can affect the WIMP itself because it may occur in the middle of a sequence of lines where Wimp_Poll is prohibited. This is the reason for some of the restrictions presented here.

The debugger does not interfere with the messages of the program being debugged, it communicates using its own message passing routines, not through Wimp_SendMessage. However, if you attempt to single step through a sequence of lines which are Wimp_Poll restricted, then the program will not behave as it would outside the debugger.

The restrictions while using the debugger can be summarised as:

1    Do not single step through a series of lines between receiving a message with event type 18 (User_Message_Recorded) and the sending of any acknowledgement. This is because the WIMP expects the program to acknowledge the message before calling Wimp_Poll.

2    In a redraw loop, the program will behave differently under the debugger than outside. If the redraw loop contains calls to Wimp_RedrawWindow when running under the debugger, the debugger will do the rest of the redraw loop for you and store the results. When you then call Wimp_GetRectangle, the debugger will return the stored values. The upshot of this is that the screen will be cleared to background completely on the first call to Wimp_RedrawWindow as opposed to each rectangle being done on each iteration of the loop.

3    Although the debugger will deal correctly with stepping through code which redirects output to a sprite, it will not deal with a program which claims the output vector itself. If you try to step through code which does this, the computer will appear to crash because the vector will be claimed through calls to Wimp_Poll.

4    The code being debugged must conform to the APCS-R standard (ARM Procedure Call Standard - RISC OS) in order to be debugged. The debugger expects the registers to be used as specified in the standard. If they are not (for example, the frame pointer register, fp, not being R11, etc) the debugger may enter a loop preventing the WIMP from being polled and effectively hanging the machine.

Easy C++ may be used from the command line instead of, or in conjunction with, the desktop front-end system described throughout this user guide. There are three main reasons why you might wish to run C from the command line instead of the desktop:

1.    To access the Easy C Library facility, which cannot be used from the desktop front�end.

2.    To use batch files for carrying out complex sequences of compile and link commands.

3.    To free extra memory for long programs which you cannot compile or link. The front-end application uses about 200K of memory which can be saved by quitting it, and then compiling and linking from the command line.

APDL and ProAction

 Index